﻿//
// IRepository.cs
//
// Authors:
//    Lasse Andreas Hauge Petersen <09547@iha.dk>
//    Søren Flohr Nielsen <10638@iha.dk>
//    Claus Jørgensen <10229@iha.dk>
//
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Diagnostics.Contracts;

namespace RSD.Data
{
    /// <summary>
    /// Represents a empty, non-generic version of <see cref="IRepository&lt;T&gt;"/>
    /// for use with Dependency Injection, or Inversion of control.
    /// </summary>
    public interface IRepository : IDisposable
    {
    }

    /// <summary>
    /// Provides strong typed facilities for querying and working with entity data as objects. 
    /// </summary>
    /// <typeparam name="T">The type of elements in the repository context.</typeparam>
    [ContractClass(typeof(Contracts.IRepositoryContract<>))]
    public interface IRepository<T> : IRepository
        where T : class
    {
        /// <summary>
        /// Returns a enumerator for all items in the repository context. 
        /// </summary>
        /// <returns>A enumerator for all items in the repository context.</returns>
        IEnumerable<T> FindAll();

        /// <summary>
        /// Finds a sequence of values from the repository context based on a predicate.
        /// </summary>
        /// <param name="predicate">A function to test each element for a condition.</param>
        /// <returns>A sequence of values from the repository context.</returns>
        IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);

        /// <summary>
        /// Notifies the set that an object that represents a new entity must be added to the set.
        /// </summary>
        /// <param name="entity">The new object to add to the set.</param>
        /// <returns>The <see cref="IRepository&lt;T&gt;"/> fluent interface</returns>
        IRepository<T> Add(T entity);

        /// <summary>
        /// Notifies the set that an object that represents an existing entity must be deleted from the set.
        /// </summary>
        /// <param name="entity">The existing object to delete from the set.</param>
        /// <returns>The <see cref="IRepository&lt;T&gt;"/> fluent interface</returns>
        IRepository<T> Remove(T entity);

        /// <summary>
        /// Persists all updates to the data source and resets change tracking in the repository context.
        /// </summary>
        /// <returns>The <see cref="IRepository&lt;T&gt;"/> fluent interface</returns>
        IRepository<T> SaveChanges();
    }
}
